<script setup>
import { reactive, ref, onMounted } from 'vue'
import { useUserStore } from '@/store'
import { getListApi, addRoleApi, editRoleApi, deleteRoleApi, assignRoleApi, saveAssignApi } from '@/api/role'
import { resetForm, objCoppy, myConfrim } from '@/utils'

// 用户信息存储对象
const userStore = useUserStore()

// 搜索区域表单
const listParm = reactive({
    // 当前页数
    currentPage: 1,
    // 页面大小
    pageSize: 10,
    // 数据总条数
    total: 0,
    // 角色名字
    roleName: ''
})
// 表格的高度
const tableHeight = ref(0)
// 表格内容
const tableData = ref([])
// 弹出框属性
const dialog = reactive({
    height: 120,
    visible: false,
    title: ''
})
// 角色选择列表
const roleTypes = [
    {
        value: '1',
        label: '系统用户'
    },
    {
        value: '2',
        label: '学生'
    }
]
// 表单数据
const addModel = reactive({
    type: '', // 0 新增 1 编辑
    roleId: '',
    roleName: '',
    roleType: '',
    remark: ''
})
// 校验规则
const rules = {
    roleName: [
        {
            trigger: 'blur',
            required: true,
            message: '请填写角色名称'
        }
    ],
    roleType: [
        {
            trigger: 'blur',
            required: true,
            message: '请选择角色类型'
        }
    ]
}
// 角色id
const roleId = ref('')
// 权限树数据
const assignTreeData = ref([])
// 角色原来的权限
const assignTreeChecked = ref([])
//    数组件的props 
const defaultProps = {
    children: 'children',
    label: 'title'
}
// 分配权限弹出框属性
const assignDialog = reactive({
    width: 400,
    height: 300,
    visible: false,
    title: ''
}
)

onMounted(() => {
    tableHeight.value = window.innerHeight - 220
})

// 获取表格数据
const getList = async () => {
    const res = await getListApi(listParm)
    tableData.value = res.data.records
    listParm.total = res.data.total
}
getList()

// 搜索按钮
const searchBtn = () => getList()
// 重置按钮
const resetBtn = () => {
    listParm.roleName = ''
    getList()
}

// 弹出框表单元素
const addRef = ref(null)
// 新增按钮
const addBtn = () => {
    dialog.title = '新增角色'
    dialog.visible = true
    // 清空上一次的表单
    resetForm(addRef.value, addModel)
    addModel.type = '0'
}

// 分配权限按钮
const assignBtn = async (row) => {
    // 清空上一次的数据
    roleId.value = ''
    assignTreeData.value = []
    assignTreeChecked.value = []
    assignDialog.title = `为 [ ${row.roleName} ] 分配权限`
    roleId.value = row.roleId
    assignDialog.visible = true
    // 获取权限树数据
    const params = {
        roleId: row.roleId,
        userId: userStore.userId
    }
    const res = await assignRoleApi(params)
    assignTreeData.value = res.data.menuList
    assignTreeChecked.value = res.data.checkList
}

// 编辑按钮
const editBtn = (row) => {
    dialog.title = '编辑角色'
    dialog.visible = true
    // 清空上一次的表单
    resetForm(addRef.value, addModel)
    // 把要编辑的数据填入表单
    objCoppy(row, addModel)
    addModel.type = '1'
}
// 删除按钮
const deleteBtn = async (row) => {
    const confirm = await myConfrim('确认删除该数据吗?')
    if (confirm) {
        const res = await deleteRoleApi({ roleId: row.roleId })
        ElMessage({ type: 'success', message: res.msg })
        // 刷新列表
        getList()
    }
}
// 页面大小改变时触发
const sizeChange = (val) => {
    listParm.pageSize = val
    getList()
}
// 页数改变时触发
const currentChange = (val) => {
    listParm.currentPage = val
    getList()
}
// 弹框确认
const onConfirm = async () => {
    await addRef.value.validate(async (valid) => {
        if (valid) {
            let res = null
            if (addModel.type === '0') {
                res = await addRoleApi(addModel)
            } else if (addModel.type === '1') {
                res = await editRoleApi(addModel)
            }
            ElMessage({ type: 'success', message: res.msg })
            // 刷新列表
            getList()
            // 关闭弹窗
            dialog.visible = false
        }
    })
}
// 弹框取消
const onClose = () => dialog.visible = false
const assignTree = ref(null)
// 分配权限弹框确认
const assignConfirm = async () => {
    const ids = assignTree.value.getCheckedKeys().concat(assignTree.value.getHalfCheckedKeys())
    const parm = {
        roleId: roleId.value,
        list: ids
    }
    if (ids.length > 0) {
        const res = await saveAssignApi(parm)
        ElMessage({ type: 'success', message: res.msg })
        assignDialog.visible = false
    } else {
        ElMessage({ type: 'error', message: '你还没有为该角色分配权限' })
    }
}
// 分配权限弹框取消
const assignClose = () => assignDialog.visible = false

</script>

<template>
    <!-- 搜索栏 -->
    <el-form :model="listParm" ref="searchRef" label-width="80px" :inline="true">
        <el-form-item>
            <el-input placeholder="请输入角色名称" v-model="listParm.roleName"></el-input>
        </el-form-item>
        <el-form-item>
            <el-button icon="Search" @click="searchBtn">搜索</el-button>
            <el-button icon="Close" style="color: #ff7670;" @click="resetBtn">重置</el-button>
            <el-button v-permission="['sys:sysRoleList:add']" type="primary" icon="Plus" @click="addBtn">新增</el-button>
        </el-form-item>
    </el-form>
    <!-- 表格 -->
    <el-table :height="tableHeight" :data="tableData" border stripe>
        <el-table-column prop="roleName" label="角色名称"></el-table-column>
        <el-table-column prop="remark" label="角色备注"></el-table-column>
        <el-table-column v-permission="['sys:sysRoleList:edit', 'sys:sysRoleList:assign', 'sys:sysRoleList:delete']"
            fixed="right" label="操作" width="300" align="center">
            <template #default="scope">
                <el-button size="small" type="primary" icon="Edit" @click="editBtn(scope.row)">编辑</el-button>
                <el-button size="small" type="success" icon="Plus" @click="assignBtn(scope.row)">分配权限</el-button>
                <el-button size="small" type="danger" icon="Delete" @click="deleteBtn(scope.row)">删除</el-button>
            </template>
        </el-table-column>
    </el-table>
    <!-- 分页 -->
    <el-pagination @size-change="sizeChange" @current-change="currentChange" :current-page.sync="listParm.currentPage"
        :page-size="listParm.pageSize" layout="total,sizes,prev,pager,next,jumper" :total="listParm.total" background>
    </el-pagination>

    <!-- 弹出框,新增或者编辑 -->
    <el-dialog v-model="dialog.visible" :width="dialog.width" :close-on-click-modal="false">
        <template #header>
            <h1>{{ dialog.title }}</h1>
        </template>
        <div :style="{ height: dialog.height + 'px' }">
            <el-form :model="addModel" ref="addRef" :rules="rules" label-width="80px">
                <el-row>
                    <el-col :span="12" :offset="0">
                        <el-form-item prop="roleName" label="角色名称">
                            <el-input v-model="addModel.roleName"></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :span="12" :offset="0">
                        <el-form-item prop="roleType" label="角色类型">
                            <el-select v-model="addModel.roleType" placeholder="请选择">
                                <el-option v-for="item in roleTypes" :key="item.value" :label="item.label"
                                    :value="item.value"></el-option>
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row>
                    <el-col :span="12" :offset="0">
                        <el-form-item label="角色备注">
                            <el-input v-model="addModel.remark"></el-input>
                        </el-form-item>
                    </el-col>
                </el-row>
            </el-form>
        </div>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="onClose">取消</el-button>
                <el-button type="primary" @click="onConfirm">确定</el-button>
            </span>
        </template>
    </el-dialog>

    <!-- 分配权限弹窗 -->
    <el-dialog v-model="assignDialog.visible" :width="assignDialog.width" :close-on-click-modal="false">
        <template #header>
            <h1>{{ assignDialog.title }}</h1>
        </template>
        <div :style="{ height: assignDialog.height + 'px' }" style="overflow-y: auto;">
            <el-tree ref="assignTree" show-checkbox empty-text="暂无数据" :data="assignTreeData"
                :default-checked-keys="assignTreeChecked" default-expand-all :props="defaultProps" node-key="menuId">
            </el-tree>
        </div>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="assignClose">取消</el-button>
                <el-button type="primary" @click="assignConfirm">确定</el-button>
            </span>
        </template>
    </el-dialog>
</template>